﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Engine;
using Game;
using Jint.Native;

namespace MFTrain
{
    public class SubsystemMFRailBlockBehavior : SubsystemBlockBehavior
    {
        protected Point3[,] m_pointsToUpdate = {
            {
                new Point3(0, 0, -1),
                new Point3(0, 1, -1),
                new Point3(0, -1, -1)
            },
            {
                new Point3(-1, 0, 0),
                new Point3(-1, 1, 0),
                new Point3(-1, -1, 0)
            },
            {
                new Point3(0, 0, 1),
                new Point3(0, 1, 1),
                new Point3(0, -1, 1)
            },
            {
                new Point3(1, 0, 0),
                new Point3(1, 1, 0),
                new Point3(1, -1, 0)
            }
        };

        public override int[] HandledBlocks => new[] { MFRailBlock.Index };

        public override void OnBlockAdded(int value, int oldValue, int x, int y, int z)
        {
            UpdateCornerState(x, y, z, 1, MFRailBlock.IsBreaker(Terrain.ExtractData(value)));
        }

        public override void OnNeighborBlockChanged(int x, int y, int z, int neighborX, int neighborY, int neighborZ)
        {
            int cell = SubsystemTerrain.Terrain.GetCellValue(x, y - 1, z);
            if (BlocksManager.Blocks[Terrain.ExtractContents(cell)].IsTransparent_(cell))
            {
                SubsystemTerrain.DestroyCell(0, x, y, z, 0, noDrop: false, noParticleSystem: false);
                return;
            }
            UpdateCornerState(x, y, z, 1, MFRailBlock.IsBreaker(Terrain.ExtractData(SubsystemTerrain.Terrain.GetCellValue(x, y, z))));
        }
        private void UpdateCornerState(int x, int y, int z, int step, bool isBreaker)
        {
            var resultType = default(int?);
            var neighbors = new bool[4];
            var raisedNeighbors = new bool[4];

            for (int i = 0; i < 4; i++)
            {
                for (int k = 0; k < 3; k++)
                {
                    var p = m_pointsToUpdate[i, k];
                    int val = SubsystemTerrain.Terrain.GetCellValueFastChunkExists(x + p.X, y + p.Y, z + p.Z);
                    if (Terrain.ExtractContents(val) == MFRailBlock.Index)
                    {
                        if (k == 1)
                            raisedNeighbors[i] = MFRailBlock.CanConnectTo(MFRailBlock.GetRailType(Terrain.ExtractData(val)), i);
                        else
                            neighbors[i] = MFRailBlock.CanConnectTo(MFRailBlock.GetRailType(Terrain.ExtractData(val)), i);
                        if (step > 0)
                            UpdateCornerState(x + p.X, y + p.Y, z + p.Z, step - 1, MFRailBlock.IsBreaker(Terrain.ExtractData(val)));
                        break;
                    }
                }
            }

            if (neighbors[0] && neighbors[3])
                resultType = 1;
            else if (neighbors[0] && neighbors[1])
                resultType = 2;
            else if (neighbors[1] && neighbors[2])
                resultType = 3;
            else if (neighbors[2] && neighbors[3])
                resultType = 0;
            else if (raisedNeighbors[2])
                resultType = 6;
            else if (raisedNeighbors[0])
                resultType = 8;
            else if (raisedNeighbors[3])
                resultType = 7;
            else if (raisedNeighbors[1])
                resultType = 9;
            else if (neighbors[0] || neighbors[2])
                resultType = 4;
            else if (neighbors[1] || neighbors[3])
                resultType = 5;

            if (resultType.HasValue)
                SubsystemTerrain.ChangeCell(x, y, z, Terrain.MakeBlockValue(MFRailBlock.Index, 0, MFRailBlock.SetRailType(isBreaker ? MFRailBlock.SetBreaker(0) : 0, resultType.Value)));
        }
    }
}
